home *** CD-ROM | disk | FTP | other *** search
-
-
-
- TTTTSSSSEEEEAAAARRRRCCCCHHHH((((3333CCCC)))) TTTTSSSSEEEEAAAARRRRCCCCHHHH((((3333CCCC))))
-
-
-
- NNNNAAAAMMMMEEEE
- tsearch, tfind, tdelete, twalk - manage binary search trees
-
- SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
- ####iiiinnnncccclllluuuuddddeeee <<<<sssseeeeaaaarrrrcccchhhh....hhhh>>>>
-
- vvvvooooiiiidddd ****ttttsssseeeeaaaarrrrcccchhhh ((((ccccoooonnnnsssstttt vvvvooooiiiidddd ****kkkkeeeeyyyy,,,, vvvvooooiiiidddd ********rrrroooooooottttpppp,,,,
- iiiinnnntttt ((((****ccccoooommmmppppaaaarrrr))))((((ccccoooonnnnsssstttt vvvvooooiiiidddd ****,,,, ccccoooonnnnsssstttt vvvvooooiiiidddd ****))))))));;;;
-
- vvvvooooiiiidddd ****ttttffffiiiinnnndddd ((((ccccoooonnnnsssstttt vvvvooooiiiidddd ****kkkkeeeeyyyy,,,, vvvvooooiiiidddd **** ccccoooonnnnsssstttt ****rrrroooooooottttpppp,,,,
- iiiinnnntttt ((((****ccccoooommmmppppaaaarrrr))))((((ccccoooonnnnsssstttt vvvvooooiiiidddd ****,,,, ccccoooonnnnsssstttt vvvvooooiiiidddd ****))))))));;;;
-
- vvvvooooiiiidddd ****ttttddddeeeelllleeeetttteeee ((((ccccoooonnnnsssstttt vvvvooooiiiidddd ****kkkkeeeeyyyy,,,, vvvvooooiiiidddd ********rrrroooooooottttpppp,,,,
- iiiinnnntttt ((((****ccccoooommmmppppaaaarrrr))))((((ccccoooonnnnsssstttt vvvvooooiiiidddd ****,,,, ccccoooonnnnsssstttt vvvvooooiiiidddd ****))))))));;;;
-
- vvvvooooiiiidddd ttttwwwwaaaallllkkkk ((((((((ccccoooonnnnsssstttt vvvvooooiiiidddd ****rrrrooooooootttt,,,, vvvvooooiiiidddd ccccoooonnnnsssstttt ((((****aaaaccccttttiiiioooonnnn))))((((vvvvooooiiiidddd ****,,,, VVVVIIIISSSSIIIITTTT,,,, iiiinnnntttt))))))));;;;
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- _t_s_e_a_r_c_h, _t_f_i_n_d, _t_d_e_l_e_t_e, and _t_w_a_l_k are routines for manipulating binary
- search trees. They are generalized from Knuth (6.2.2) Algorithms T and
- D. All comparisons are done with a user-supplied routine. This routine
- is called with two arguments, the pointers to the elements being
- compared. It returns an integer less than, equal to, or greater than 0,
- according to whether the first argument is to be considered less than,
- equal to or greater than the second argument. The comparison function
- need not compare every byte, so arbitrary data may be contained in the
- elements in addition to the values being compared.
-
- _t_s_e_a_r_c_h is used to build and access the tree. KKKKeeeeyyyy is a pointer to a
- datum to be accessed or stored. If there is a datum in the tree equal to
- *key (the value pointed to by key), a pointer to this found datum is
- returned. Otherwise, *key is inserted, and a pointer to it returned.
- Only pointers are copied, so the calling routine must store the data.
- RRRRoooooooottttpppp points to a variable that points to the root of the tree. A NULL
- value for the variable pointed to by rrrroooooooottttpppp denotes an empty tree; in this
- case, the variable will be set to point to the datum which will be at the
- root of the new tree.
-
- Like _t_s_e_a_r_c_h, _t_f_i_n_d will search for a datum in the tree, returning a
- pointer to it if found. However, if it is not found, _t_f_i_n_d will return a
- NULL pointer. The arguments for _t_f_i_n_d are the same as for _t_s_e_a_r_c_h.
-
- _T_d_e_l_e_t_e deletes a node from a binary search tree. The arguments are the
- same as for _t_s_e_a_r_c_h. The variable pointed to by rrrroooooooottttpppp will be changed if
- the deleted node was the root of the tree. _T_d_e_l_e_t_e returns a pointer to
- the parent of the deleted node, or a NULL pointer if the node is not
- found.
-
- _T_w_a_l_k traverses a binary search tree. RRRRooooooootttt is the root of the tree to be
- traversed. (Any node in a tree may be used as the root for a walk below
- that node.) _A_c_t_i_o_n is the name of a routine to be invoked at each node.
- This routine is, in turn, called with three arguments. The first
-
-
-
- PPPPaaaaggggeeee 1111
-
-
-
-
-
-
- TTTTSSSSEEEEAAAARRRRCCCCHHHH((((3333CCCC)))) TTTTSSSSEEEEAAAARRRRCCCCHHHH((((3333CCCC))))
-
-
-
- argument is the address of the node being visited. The second argument
- is a value from an enumeration data type _t_y_p_e_d_e_f _e_n_u_m { _p_r_e_o_r_d_e_r,
- _p_o_s_t_o_r_d_e_r, _e_n_d_o_r_d_e_r, _l_e_a_f } _V_I_S_I_T; (defined in the <_s_e_a_r_c_h._h> header
- file), depending on whether this is the first, second or third time that
- the node has been visited (during a depth-first, left-to-right traversal
- of the tree), or whether the node is a leaf. The third argument is the
- level of the node in the tree, with the root being level zero.
-
- The pointers to the key and the root of the tree should be of type
- pointer-to-element, and cast to type pointer-to-character. Similarly,
- although declared as type pointer-to-character, the value returned should
- be cast into type pointer-to-element.
-
- EEEEXXXXAAAAMMMMPPPPLLLLEEEE
- The following code reads in strings and stores structures containing a
- pointer to each string and a count of its length. It then walks the
- tree, printing out the stored strings and their lengths in alphabetical
- order.
-
- #include <search.h>
- #include <stdio.h>
-
- struct node { /* pointers to these are stored in the tree */
- char *string;
- int length;
- };
- char string_space[10000]; /* space to store strings */
- struct node nodes[500]; /* nodes to store */
- struct node *root = NULL; /* this points to the root */
-
- main( )
- {
- char *strptr = string_space;
- struct node *nodeptr = nodes;
- void print_node( ), twalk( );
- int i = 0, node_compare( );
-
- while (gets(strptr) != NULL && i++ < 500) {
- /* set node */
- nodeptr->string = strptr;
- nodeptr->length = strlen(strptr);
- /* put node into the tree */
- (void) tsearch((char *)nodeptr, (char **) &root,
- node_compare);
- /* adjust pointers, so we don't overwrite tree */
- strptr += nodeptr->length + 1;
- nodeptr++;
- }
- twalk((char *)root, print_node);
- }
- /*
- This routine compares two nodes, based on an
-
-
-
- PPPPaaaaggggeeee 2222
-
-
-
-
-
-
- TTTTSSSSEEEEAAAARRRRCCCCHHHH((((3333CCCC)))) TTTTSSSSEEEEAAAARRRRCCCCHHHH((((3333CCCC))))
-
-
-
- alphabetical ordering of the string field.
- */
- int
- node_compare(node1, node2)
- char *node1, *node2;
- {
- return strcmp(((struct node *)node1)->string,
- ((struct node *) node2)->string);
- }
- /*
- This routine prints out a node, the first time
- twalk encounters it.
- */
- void
- print_node(node, order, level)
- char **node;
- VISIT order;
- int level;
- {
- if (order == postorder || order == leaf) {
- (void)printf("string = %20s, length = %d\n",
- (*((struct node **)node))->string,
- (*((struct node **)node))->length);
- }
- }
-
- SSSSEEEEEEEE AAAALLLLSSSSOOOO
- bsearch(3C), hsearch(3C), lsearch(3C).
-
- DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS
- A NULL pointer is returned by _t_s_e_a_r_c_h if there is not enough space
- available to create a new node.
- A NULL pointer is returned by _t_f_i_n_d and _t_d_e_l_e_t_e if rrrroooooooottttpppp is NULL on
- entry.
- If the datum is found, both _t_s_e_a_r_c_h and _t_f_i_n_d return a pointer to it. If
- not, _t_f_i_n_d returns NULL, and _t_s_e_a_r_c_h returns a pointer to the inserted
- item.
-
- WWWWAAAARRRRNNNNIIIINNNNGGGGSSSS
- The rrrrooooooootttt argument to _t_w_a_l_k is one level of indirection less than the
- rrrroooooooottttpppp arguments to _t_s_e_a_r_c_h and _t_d_e_l_e_t_e.
- There are two nomenclatures used to refer to the order in which tree
- nodes are visited. _t_s_e_a_r_c_h uses preorder, postorder and endorder to
- respectively refer to visiting a node before any of its children, after
- its left child and before its right, and after both its children. The
- alternate nomenclature uses preorder, inorder and postorder to refer to
- the same visits, which could result in some confusion over the meaning of
- postorder.
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 3333
-
-
-
-
-
-
- TTTTSSSSEEEEAAAARRRRCCCCHHHH((((3333CCCC)))) TTTTSSSSEEEEAAAARRRRCCCCHHHH((((3333CCCC))))
-
-
-
- CAVEAT
- If the calling function alters the pointer to the root, results are
- unpredictable.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 4444
-
-
-
-